package com.cans.ssoserver.web;

import com.cans.base.dto.ResDto;
import com.cans.base.model.SsoUser;
import com.cans.ssoserver.service.user.api.ISsoUserService;
import com.cans.ssoserver.util.TicketUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * @author cans
 * @date 2018/6/18
 * @description 单点登录web层
 */
@Controller
@RequestMapping("/sso")
public class SsoUserController {

    @Resource
    private ISsoUserService ssoUserService;

    /**
     * 去登陆
     * @return
     */
    @GetMapping(value = "/goLogin")
    public String goLogin(){

        return "sso/login";
    }

    /**
     * 登录
     * @return
     */
    @PostMapping(value = "/login")
    public String login(final SsoUser ssoUser, HttpServletRequest request, Model model){

        List<SsoUser> userList = ssoUserService.findAll((root, criteriaQuery, criteriaBuilder) -> {

            List<Predicate> list = new ArrayList<>();
            if (null != ssoUser && !StringUtils.isEmpty(ssoUser.getUsername())) {
                list.add(criteriaBuilder.equal(root.get("username"), ssoUser.getUsername()));
            }

            if (null != ssoUser && !StringUtils.isEmpty(ssoUser.getPassword())) {
                list.add(criteriaBuilder.equal(root.get("password"), ssoUser.getPassword()));
            }

            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        });

        if(userList == null || userList.isEmpty()){
            // 认证失败,返回登录页
            model.addAttribute("passwordErr","用户名或密码错误");

            return "sso/login";
        }

        request.getSession().setAttribute("ssoUser",userList.get(0));


        Object object = request.getSession().getAttribute("redirectUrl");
        if(object instanceof String){
            request.getSession().removeAttribute("redirectUrl");
            String redirectUrl = object.toString();
            return "redirect:" + redirectUrl + "?ticket=" + ssoUser.getUsername();
        }

        return "redirect:/";
    }

    /**
     * 去注册
     * @return
     */
    @GetMapping(value = "/goRegister")
    public String goRegister(){

        return "sso/register";
    }

    /**
     * 注册
     * @return
     */
    @PostMapping(value = "/register")
    @ResponseBody
    public ResDto register(SsoUser ssoUser){


        List<SsoUser> userList = ssoUserService.findAll((root, criteriaQuery, criteriaBuilder) -> {

            List<Predicate> list = new ArrayList<>();
            if (null != ssoUser && !StringUtils.isEmpty(ssoUser.getUsername())) {
                list.add(criteriaBuilder.equal(root.get("username"), ssoUser.getUsername()));
            }

            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        });

        if(userList != null && !userList.isEmpty()){
            return ResDto.fait(userList.get(0).getUsername() + ":用户名已存在,不可重复注册");
        }

        ssoUser.setEnable(1);
        ssoUserService.save(ssoUser);

        return ResDto.success();
    }

    /**
     * 校验用户名
     * @return
     */
    @PostMapping(value = "/checkUsername")
    @ResponseBody
    public ResDto checkUsername(String username){

        List<SsoUser> userList = ssoUserService.findAll((root, criteriaQuery, criteriaBuilder) -> {

            List<Predicate> list = new ArrayList<>();
            if ( !StringUtils.isEmpty(username)) {
                list.add(criteriaBuilder.equal(root.get("username"), username));
            }

            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        });

        if(userList == null || userList.isEmpty()){
            return ResDto.success();
        }

        return ResDto.fait("此用户名已注册");
    }

    /**
     * 获取用户信息
     * @return
     */
    @GetMapping(value = "/user")
    @ResponseBody
    public ResDto getUser(HttpServletRequest request){

        SsoUser ssoUser = (SsoUser)request.getSession().getAttribute("ssoUser");

        return ResDto.success(ssoUser);
    }

    /**
     * 登出
     * @return
     */
    @GetMapping(value = "/logout")
    public String logout(HttpServletRequest request,String redirectUrl){

        SsoUser ssoUser = (SsoUser)request.getSession().getAttribute("ssoUser");
        TicketUtils.removeTicket(ssoUser.getUsername());
        request.getSession().setAttribute("ssoUser",null);

        if(!StringUtils.isEmpty(redirectUrl)){
            return "redirect:" + redirectUrl;
        }

        return "redirect:/";
    }

    /**
     * 单点登录请求
     * @param redirectUrl
     * @return
     */
    @GetMapping("/ssoLogin")
    public String ssoLogin(HttpServletRequest request,String redirectUrl){

        Object ssoUser = request.getSession().getAttribute("ssoUser");

        if(ssoUser instanceof SsoUser){
            String ticketUrl = redirectUrl + "?ticket=" + ((SsoUser) ssoUser).getUsername();
            return "redirect:" + ticketUrl;
        }else {
            request.getSession().setAttribute("redirectUrl",redirectUrl);
            return "redirect:/sso/goLogin";
        }

    }

    /**
     * 验证ticket
     * @param ticket
     * @return
     */
    @GetMapping("/ticket")
    @ResponseBody
    public ResDto ticket(String ticket){

        return ResDto.success(TicketUtils.getTicket(ticket));
    }
}
